1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
// app/(vendor)/stage-submissions/page.tsx
import * as React from "react"
import { searchParamsCache } from "@/lib/vendor-document-list/plant/upload/validation"
import { StageSubmissionsTable } from "@/lib/vendor-document-list/plant/upload/table"
import { redirect } from "next/navigation"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle
} from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { getServerSession } from 'next-auth/next'
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
import { getStageSubmissions, getProjects, getSubmissionStats } from "@/lib/vendor-document-list/plant/upload/service"
import db from "@/db/db"
import { eq } from "drizzle-orm"
import { vendors } from "@/db/schema"
export default async function StageSubmissionsPage({
searchParams,
}: {
searchParams: Promise<Record<string, string | string[] | undefined>>
}) {
// Session 체크
const session = await getServerSession(authOptions)
if (!session?.user?.companyId) {
redirect("/partners")
}
const vendor = await db.query.vendors.findFirst({
where: eq(vendors.id, session.user.companyId),
columns: {
vendorName: true,
vendorCode: true,
}
})
const params = searchParamsCache.parse(await searchParams)
const submissionsPromise = getStageSubmissions(params)
const projectsPromise = getProjects()
const statsPromise = getSubmissionStats()
const [submissions, projects, stats] = await Promise.all([
submissionsPromise,
projectsPromise,
statsPromise
])
return (
<div className="container mx-auto py-6 space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold tracking-tight">My Stage Submissions</h2>
<p className="text-muted-foreground mt-1">
Manage document submissions for your approved stages (SWP)
</p>
</div>
<div className="">
{/* <Badge variant="outline" className="gap-1"> */}
{/* <span className="font-semibold">Company:</span> */}
<span className="font-semibold"> {vendor.vendorName || "Your Company"}</span>
<p className="text-muted-foreground text-sm">
Buyer Approved Documents
</p>
{/* </Badge> */}
</div>
</div>
{/* Stats Cards */}
<div className="grid gap-4 md:grid-cols-4">
<Card>
<CardHeader className="pb-2">
<CardDescription>Pending Submissions</CardDescription>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">
{stats.pending}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardDescription>Overdue</CardDescription>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-destructive">
{stats.overdue}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardDescription>Awaiting Sync</CardDescription>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-warning">
{stats.awaitingSync}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardDescription>Completed</CardDescription>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-success">
{stats.completed}
</div>
</CardContent>
</Card>
</div>
{/* Main Table */}
<Card>
<CardHeader>
<CardTitle>Your Submission List</CardTitle>
<CardDescription>
View and manage document submissions for your company's stages
</CardDescription>
</CardHeader>
<CardContent>
<React.Suspense
fallback={
<div className="flex h-[400px] items-center justify-center">
<div className="animate-pulse text-muted-foreground">
Loading your submissions...
</div>
</div>
}
>
<StageSubmissionsTable
promises={Promise.all([
{ data: submissions.data, pageCount: submissions.pageCount },
{ projects: projects.map(p => ({ id: p.id, code: p.code || "" })) }
])}
selectedProjectId={params.projectId}
/>
</React.Suspense>
</CardContent>
</Card>
</div>
)
}
|